/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.inspur.edp.metadata.rtcustomization.servermanager.dac;

import com.inspur.edp.metadata.rtcustomization.api.entity.GspMdCustomContent;
import com.inspur.edp.metadata.rtcustomization.api.entity.GspMdCustomContentData;
import com.inspur.edp.metadata.rtcustomization.common.PredicateUtils;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import lombok.var;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class GeneratedRepo {
	private CustomizationDataProducer cdp;
	public GeneratedRepo(CustomizationDataProducer cdp) {
		this.cdp = cdp;
	}

	public GspMdCustomContent getGeneratedMetadataById(String id) {
		if (StringUtils.isEmpty(id)) {
			return null;
		}
		CustomizationMetadataRepository customizationMetadataRepository = SpringBeanUtils.getBean(CustomizationMetadataRepository.class);
		return customizationMetadataRepository.findById(id).orElse(null);
	}

	public List<GspMdCustomContent> getGeneratedList() {
//		sql = "select id,code,name,type,isextend,bizobjid,namespace from gspmdcustomcontent";
//		return getMetadataFromDatabase(sql);
		CustomizationMetadataRepository customizationMetadataRepository = SpringBeanUtils.getBean(CustomizationMetadataRepository.class);
		List<GspMdCustomContentData> gspMdCustomContentDataList = customizationMetadataRepository.findAllGspMdCustomContents();
		return getMetadataFromDatabase(gspMdCustomContentDataList);
	}

	/**
	 * 根据条件获取生成的元数据列表
	 *
	 * @param keyword
	 * @param metadataTypes
	 * @param beginNum
	 * @param size
	 * @return
	 */
	public List<GspMdCustomContent> getGeneratedListByCondition(String keyword, String bizobjectID, List<String> metadataTypes, int beginNum, int size) {
		EntityManager entityManager = cdp.getEm();
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<GspMdCustomContent> query = cb.createQuery(GspMdCustomContent.class);
		Root<GspMdCustomContent> root = query.from(GspMdCustomContent.class);
		// 实际查询字段
		query.multiselect(root.get("id"), root.get("code"), root.get("name"), root.get("type"), root.get("bizObjId"), root.get("isExtend"), root.get("nameSpace"));
		Predicate finalPredicate = PredicateUtils.buildMdQueryPredicate(keyword, bizobjectID, metadataTypes, null,cb, root,GspMdCustomContent.class);
		query.where(finalPredicate);

		// 执行查询，获取总记录数
		List<GspMdCustomContent> resultList = entityManager.createQuery(query).setFirstResult(beginNum).setMaxResults(size).getResultList();
		return resultList;
	}

	/**
	 * 根据条件获取生成的元数据的数量
	 *
	 * @param keyword
	 * @param metadataTypes
	 * @return
	 */
	public long getGeneratedListCountByCondition(String keyword, String bizobjectID, List<String> metadataTypes) {
		EntityManager entityManager = cdp.getEm();
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<Long> query = cb.createQuery(Long.class);
		Root<GspMdCustomContent> root = query.from(GspMdCustomContent.class);
		// 实际查询字段
		query.select(cb.count(root));
		Predicate finalPredicate = PredicateUtils.buildMdQueryPredicate(keyword, bizobjectID, metadataTypes, null, cb, root,GspMdCustomContent.class);
		query.where(finalPredicate);

		// 执行查询，获取总记录数
		Long count = entityManager.createQuery(query).getSingleResult();
		return count;
	}

	public List<GspMdCustomContent> getGeneratedListById(String id) {
//		sql = "select id,code,name,type,isextend,bizobjid,namespace from gspmdcustomcontent where id='" + id+"'";
//		return getMetadataFromDatabase(sql);
		CustomizationMetadataRepository customizationMetadataRepository = SpringBeanUtils.getBean(CustomizationMetadataRepository.class);
		List<GspMdCustomContentData> gspMdCustomContentDataList = customizationMetadataRepository.findAllGspMdCustomContents(id);
		return getMetadataFromDatabase(gspMdCustomContentDataList);
	}

	private List<GspMdCustomContent> getMetadataFromDatabase(String sql) {
		List<GspMdCustomContent> metadataList = new ArrayList<>();
		Query query = cdp.getEm().createNativeQuery(sql);
		List<Object[]> result = query.getResultList();

		for(Object[] item : result){
			var metadata = new GspMdCustomContent();
			metadata.setId((String) item[0]);
			metadata.setCode((String) item[1]);
			metadata.setName((String) item[2]);
			metadata.setType((String) item[3]);
			metadata.setIsExtend((Character)item[4]);
			metadata.setBizObjId((String) item[5]);
			metadata.setNameSpace((String) item[6]);
			metadataList.add(metadata);
		}
		return metadataList;
	}

	private List<GspMdCustomContent> getMetadataFromDatabase(List<GspMdCustomContentData> gspMdCustomContentDataList) {
		List<GspMdCustomContent> metadataList = new ArrayList<>();
		if(CollectionUtils.isEmpty(gspMdCustomContentDataList)){
			return metadataList;
		}
		for (GspMdCustomContentData gspMdCustomContentData : gspMdCustomContentDataList) {
			var metadata = new GspMdCustomContent();
			BeanUtils.copyProperties(gspMdCustomContentData,metadata);
			metadataList.add(metadata);
		}
		return metadataList;
	}

	public List<GspMdCustomContent> findAllLastChangedOn() {
		CustomizationMetadataRepository customizationMetadataRepository = SpringBeanUtils.getBean(CustomizationMetadataRepository.class);
		return customizationMetadataRepository.findAllLastChangedOn();
	}

	public void updateLastChangedOnWhereIsNull() {
		CustomizationMetadataRepository customizationMetadataRepository = SpringBeanUtils.getBean(CustomizationMetadataRepository.class);
		customizationMetadataRepository.updateLastChangedOnWhereIsNull(LocalDateTime.now());
	}
}
